package com.zpark.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zpark.dto.AppointmentQueryDTO;
import com.zpark.entity.patients.PatientAppointments;
import com.zpark.mapper.PatientAppointmentsMapper;
import com.zpark.service.PatientAppointmentsService;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.Collections;
import java.util.Date;
import java.util.List;

/**
 * 患者预约服务实现类（适配appointment_id为主键版本）
 */
@Service
public class PatientAppointmentsServiceImpl
    extends ServiceImpl<PatientAppointmentsMapper, PatientAppointments>
    implements PatientAppointmentsService {

    // 预约ID前缀
    private static final String APPOINTMENT_PREFIX = "APT";
    // 预约ID日期格式
    private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyyMMdd");

    @Override
    public PatientAppointments createAppointment(PatientAppointments appointment) {
        // 生成预约ID（格式：APT+年月日+4位随机字母）
        String appointmentId = generateAppointmentId();
        appointment.setAppointmentId(appointmentId);
        appointment.setAppointmentStatus("PENDING");
        appointment.setCreatedAt(new Date());
        // 设置默认问诊类型
        if (StringUtils.isBlank(appointment.getConsultationType())) {
            appointment.setConsultationType("WESTERN"); // 默认西医问诊
        }

        this.save(appointment);
        return appointment;
    }

    // 删除预约记录
    @Override
    public PatientAppointments deleteAppointment(String appointmentId) {
        // 先查询记录
        PatientAppointments appointment = getAppointmentByAppointmentId(appointmentId);
        if (appointment == null) {
            throw new RuntimeException("预约记录不存在");
        }

        // 删除记录
        boolean success = this.remove(new LambdaQueryWrapper<PatientAppointments>()
            .eq(PatientAppointments::getAppointmentId, appointmentId));

        return success ? appointment : null;
    }

    @Override
    public PatientAppointments updateAppointment(PatientAppointments newData) {
        if (newData.getAppointmentId() == null) {
            throw new IllegalArgumentException("预约ID不能为空");
        }

        // 1. 查询原记录
        PatientAppointments original = this.getAppointmentByAppointmentId(newData.getAppointmentId());
        if (original == null) {
            throw new RuntimeException("原预约记录不存在");
        }

        // 2. 设置新记录的属性
        PatientAppointments newRecord = new PatientAppointments();
        BeanUtils.copyProperties(newData, newRecord);

        // 3. 生成新的预约
        newRecord.setAppointmentId(generateAppointmentId());
        newRecord.setCreatedAt(new Date());
        newRecord.setUpdatedAt(new Date());

        // 4. 保存新记录
        this.save(newRecord);

        // 5. 更新原记录为历史状态
        original.setUpdatedAt(new Date());
        this.updateById(original);

        return newRecord;
    }

    @Override
    public boolean cancelAppointment(String appointmentId, String cancelReason) {
        return this.update(new LambdaUpdateWrapper<PatientAppointments>()
            .eq(PatientAppointments::getAppointmentId, appointmentId)
            .set(PatientAppointments::getAppointmentStatus, "已取消")
            .set(PatientAppointments::getCancelReason, cancelReason)
            .set(PatientAppointments::getCancelTime, new Date())
            .set(PatientAppointments::getUpdatedAt, new Date()));
    }

    @Override
    public boolean confirmAppointment(String appointmentId) {
        return this.update(new LambdaUpdateWrapper<PatientAppointments>()
            .eq(PatientAppointments::getAppointmentId, appointmentId)
            .set(PatientAppointments::getAppointmentStatus, "CONFIRMED")
            .set(PatientAppointments::getUpdatedAt, new Date()));
    }

    @Override
    public boolean completeAppointment(String appointmentId) {
        return this.update(new LambdaUpdateWrapper<PatientAppointments>()
            .eq(PatientAppointments::getAppointmentId, appointmentId)
            .set(PatientAppointments::getAppointmentStatus, "COMPLETED")
            .set(PatientAppointments::getUpdatedAt, new Date()));
    }

    @Override
    public PatientAppointments getAppointmentByAppointmentId(String appointmentId) {
        return this.getOne(new LambdaQueryWrapper<PatientAppointments>()
            .eq(PatientAppointments::getAppointmentId, appointmentId));
    }

    @Override
    public List<PatientAppointments> getAppointmentsByPatientId(Integer patientId) {
        return this.list(new LambdaQueryWrapper<PatientAppointments>()
            .eq(PatientAppointments::getPatientId, patientId)
            .orderByDesc(PatientAppointments::getAppointmentDate));
    }

    @Override
    public List<PatientAppointments> getAppointmentsByDoctorId(String doctorId) {
        return this.list(new LambdaQueryWrapper<PatientAppointments>()
            .eq(PatientAppointments::getDoctorId, doctorId)
            .orderByDesc(PatientAppointments::getAppointmentDate));
    }

    @Override
    public List<PatientAppointments> getAppointmentsByStatus(String status) {
        return this.list(new LambdaQueryWrapper<PatientAppointments>()
            .eq(PatientAppointments::getAppointmentStatus, status)
            .orderByDesc(PatientAppointments::getAppointmentDate));
    }

    @Override
    public List<PatientAppointments> getPendingAppointments() {
        return this.getAppointmentsByStatus("PENDING");
    }

    @Override
    public boolean sendAppointmentReminder(String appointmentId) {
        return this.update(new LambdaUpdateWrapper<PatientAppointments>()
            .eq(PatientAppointments::getAppointmentId, appointmentId)
            .set(PatientAppointments::getUpdatedAt, new Date()));
    }

    @Override
    public boolean checkAppointmentConflict(String doctorId, Date appointmentDate, String timeSlot) {
        return this.count(new LambdaQueryWrapper<PatientAppointments>()
            .eq(PatientAppointments::getDoctorId, doctorId)
            .eq(PatientAppointments::getAppointmentDate, appointmentDate)
            .eq(PatientAppointments::getTimeSlot, timeSlot)
            .notIn(PatientAppointments::getAppointmentStatus, "CANCELLED", "COMPLETED")) > 0;
    }

    @Override
    public long countAppointments(String status) {
        return this.count(new LambdaQueryWrapper<PatientAppointments>()
            .eq(status != null, PatientAppointments::getAppointmentStatus, status));
    }

    @Override
    public List<PatientAppointments> getRecentAppointmentsByPatient(Integer patientId, int limit) {
        return this.list(new LambdaQueryWrapper<PatientAppointments>()
            .eq(PatientAppointments::getPatientId, patientId)
            .orderByDesc(PatientAppointments::getAppointmentDate)
            .last("LIMIT " + limit));
    }

    @Override
    public List<PatientAppointments> getRecentAppointmentsByDoctor(String doctorId, int limit) {
        return this.list(new LambdaQueryWrapper<PatientAppointments>()
            .eq(PatientAppointments::getDoctorId, doctorId)
            .orderByDesc(PatientAppointments::getAppointmentDate)
            .last("LIMIT " + limit));
    }

    @Override
    public List<PatientAppointments> getAllAppointments() {
        return this.list(new LambdaQueryWrapper<PatientAppointments>()
            .orderByDesc(PatientAppointments::getAppointmentDate));
    }

    @Override
    public List<PatientAppointments> getAppointmentHistory(String appointmentId) {
        // 先找到原始ID（去掉版本后缀）
        String originalId = appointmentId.substring(0, appointmentId.lastIndexOf("-"));

        return this.list(new LambdaQueryWrapper<PatientAppointments>()
            .likeRight(PatientAppointments::getAppointmentId, originalId)
            );
    }

    @Override
    public List<PatientAppointments> queryAppointments(AppointmentQueryDTO queryDTO) {
        LambdaQueryWrapper<PatientAppointments> queryWrapper = new LambdaQueryWrapper<>();

        // 患者ID筛选
        if (queryDTO.getPatientId() != null) {
            queryWrapper.eq(PatientAppointments::getPatientId, queryDTO.getPatientId());
        }


        // 状态筛选
        if (StringUtils.isNotBlank(queryDTO.getStatus())) {
            // 将前端状态值转换为数据库存储的状态值
            String status = convertStatusToDbValue(queryDTO.getStatus());
            queryWrapper.eq(PatientAppointments::getAppointmentStatus, status);
        }

        // 问诊类型筛选
        if (queryDTO.getConsultationType() != null) {
            queryWrapper.eq(PatientAppointments::getConsultationType, queryDTO.getConsultationType());
        }

        // 时间范围筛选
        if (queryDTO.getStartDate() != null && queryDTO.getEndDate() != null) {
            queryWrapper.between(PatientAppointments::getAppointmentDate,
                queryDTO.getStartDate(),
                queryDTO.getEndDate());
        } else if (queryDTO.getStartDate() != null) {
            queryWrapper.ge(PatientAppointments::getAppointmentDate, queryDTO.getStartDate());
        } else if (queryDTO.getEndDate() != null) {
            queryWrapper.le(PatientAppointments::getAppointmentDate, queryDTO.getEndDate());
        }

        // 搜索查询
        if (StringUtils.isNotBlank(queryDTO.getSearchQuery())) {
            queryWrapper.and(wrapper ->
                wrapper.like(PatientAppointments::getDoctorName, queryDTO.getSearchQuery())
                    .or()
                    .like(PatientAppointments::getDoctorDepartment, queryDTO.getSearchQuery())
                    .or()
                    .like(PatientAppointments::getClinicLocation, queryDTO.getSearchQuery())
            );
        }

        // 排序
        queryWrapper.orderByDesc(PatientAppointments::getAppointmentDate);

        return this.list(queryWrapper);
}

    private String convertStatusToDbValue(String frontendStatus) {
        switch (frontendStatus) {
            case "PENDING":
                return "待确认";
            case "CONFIRMED":
                return "已预约";
            case "COMPLETED":
                return "已完成";
            case "CANCELED":
                return "已取消";
            case "CANCELLED":
                return "被取消";
            default:
                return frontendStatus;
        }
    }

    @Override
    public boolean updateAppointmentStatus(String appointmentId, String newStatus) {
        return this.update(new LambdaUpdateWrapper<PatientAppointments>()
            .eq(PatientAppointments::getAppointmentId, appointmentId)
            .set(PatientAppointments::getAppointmentStatus, newStatus)
            .set(PatientAppointments::getUpdatedAt, new Date()));
    }

    /**
     * 生成预约ID（APT+年月日+4位随机字母）
     */
    private String generateAppointmentId() {
        // 使用Apache Commons Lang生成4位随机字母
        String randomLetters = RandomStringUtils.randomAlphabetic(4).toUpperCase();
        return APPOINTMENT_PREFIX + DATE_FORMAT.format(new Date()) + randomLetters;
    }

    @Override
    public IPage<PatientAppointments> listAppointmentsByPage(Page<PatientAppointments> page, AppointmentQueryDTO queryDTO) {
        LambdaQueryWrapper<PatientAppointments> queryWrapper = new LambdaQueryWrapper<>();

        // 患者ID筛选
        if (queryDTO.getPatientId() != null) {
            queryWrapper.eq(PatientAppointments::getPatientId, queryDTO.getPatientId());
        }

        // 状态筛选
        if (StringUtils.isNotBlank(queryDTO.getStatus())) {
            String status = convertStatusToDbValue(queryDTO.getStatus());
            queryWrapper.eq(PatientAppointments::getAppointmentStatus, status);
        }

        // 问诊类型筛选
        if (queryDTO.getConsultationType() != null) {
            queryWrapper.eq(PatientAppointments::getConsultationType, queryDTO.getConsultationType());
        }

        // 时间范围筛选
        if (queryDTO.getStartDate() != null && queryDTO.getEndDate() != null) {
            queryWrapper.between(PatientAppointments::getAppointmentDate,
                queryDTO.getStartDate(),
                queryDTO.getEndDate());
        } else if (queryDTO.getStartDate() != null) {
            queryWrapper.ge(PatientAppointments::getAppointmentDate, queryDTO.getStartDate());
        } else if (queryDTO.getEndDate() != null) {
            queryWrapper.le(PatientAppointments::getAppointmentDate, queryDTO.getEndDate());
        }

        // 搜索查询
        if (StringUtils.isNotBlank(queryDTO.getSearchQuery())) {
            queryWrapper.and(wrapper ->
                wrapper.like(PatientAppointments::getDoctorName, queryDTO.getSearchQuery())
                    .or()
                    .like(PatientAppointments::getDoctorDepartment, queryDTO.getSearchQuery())
                    .or()
                    .like(PatientAppointments::getClinicLocation, queryDTO.getSearchQuery())
            );
        }

        // 排序
        queryWrapper.orderByDesc(PatientAppointments::getAppointmentDate);

        return this.page(page, queryWrapper);
    }
}
